package com.leoren.run.activity.run;


import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.media.Image;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.Pair;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;


import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.Polyline;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.maps.utils.SpatialRelationUtil;
import com.amap.api.maps.utils.overlay.SmoothMoveMarker;
import com.amap.api.navi.AMapNavi;
import com.bumptech.glide.RequestBuilder;
import com.leoren.run.R;
import com.leoren.run.activity.share.GenSharePicActivity;
import com.leoren.run.activity.share.PublishCommentActivity;
import com.leoren.run.common.Const;
import com.leoren.run.common.ResponseCode;
import com.leoren.run.common.ServerResponse;
import com.leoren.run.common.UrlConstants;
import com.leoren.run.dbbean.UserDB;
import com.leoren.run.log.L;
import com.leoren.run.utils.DateParseUtil;
import com.leoren.run.utils.GsonUtil;
import com.leoren.run.utils.Http.OkHttp.CommonOkHttpClient;
import com.leoren.run.utils.Http.OkHttp.exception.OkHttpException;
import com.leoren.run.utils.Http.OkHttp.listener.DisposeDataHandle;
import com.leoren.run.utils.Http.OkHttp.listener.DisposeDataListener;
import com.leoren.run.utils.Http.OkHttp.request.CommonRequest;
import com.leoren.run.utils.LocationUtils;
import com.leoren.run.utils.MyMapUtils;
import com.leoren.run.utils.MyNumberUtils;
import com.leoren.run.utils.NumberUtils;
import com.leoren.run.utils.TimeUtils;
import com.leoren.run.utils.ToastUtil;
import com.leoren.run.utils.trace.PathUtils;
import com.leoren.run.vo.RunMapRouteVo;
import com.leoren.run.vo.RunRecordVo;
import com.leoren.run.vo.ShareDataVo;
import com.leoren.run.vo.User;

import org.litepal.LitePal;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

import okhttp3.FormBody;
import okhttp3.Request;
import okhttp3.RequestBody;
import retrofit2.http.Url;

/**
 * 具体地图路径信息 开始跑步并保存用户跑步记录信息
 */
public class StartRunActivity extends AppCompatActivity implements View.OnClickListener, View.OnLongClickListener {

    private Long mapId;
    private RunMapRouteVo mapVo;

    private AMap map = null;
    private MapView mapView;
    private Polyline polyline;
    List<LatLng> pathList = null;
    private Marker startMarker, endMarker, actualRoleMarker;
    private List<LatLng> actualPathList = null;
    private SmoothMoveMarker roleMarker;
    private LatLng startLocation;
    private LatLng endLocation;

    private LatLng nowLocation;

    private ImageButton startBtn, endBtn;
    private TextView distanceText;
    private TextView timeText;
    private TimeUtils timeUtils;

    private int timeCount = 0;

    private AMapNavi aMapNavi = null;

    private int status = 0;   //0  刚进页面状态    1开始阶段   2 暂停阶段  3 停止阶段

    private AMapLocationClient locationClient = null;
    private AMapLocationClientOption locationOption = null;

    private ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start_run);

        getData();

        startBtn = findViewById(R.id.start_run_btn);
        startBtn.setOnClickListener(this);
        startBtn.setOnLongClickListener(this);

        endBtn = findViewById(R.id.end_run_btn);
        endBtn.setOnClickListener(this);
        endBtn.setOnLongClickListener(this);

        distanceText = findViewById(R.id.run_distance);
        timeText = findViewById(R.id.run_time);
        timeUtils = new TimeUtils(timeText);


        mapView = findViewById(R.id.run_map);
        mapView.onCreate(savedInstanceState);
        map = mapView.getMap();
        map.moveCamera(CameraUpdateFactory.zoomTo(4));

        initLocation();
    }

    /**
     * 地图定位
     */
    AMapLocationListener locationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation location) {
            if (null != location) {
                //errCode等于0代表定位成功，其他的为定位失败，具体的可以参照官网定位错误码说明
                if(location.getErrorCode() == 0){
                    Double lat = location.getLatitude();
                    Double lng = location.getLongitude();
                    nowLocation = new LatLng(lat, lng);
                    startActualRun();
                    L.e("现在的经纬度是" + nowLocation);
                } else {
                    ToastUtil.MakeToast("定位失败，loc is null");
                }

            } else {
                ToastUtil.MakeToast("定位失败，loc is null");
            }
        }
    };

    /**
     * 初始化定位控件等信息
     */
    private void initLocation(){
        locationClient = new AMapLocationClient(this.getApplicationContext());
        locationOption = getDefaultOption();
        locationClient.setLocationOption(locationOption);
        locationClient.setLocationListener(locationListener);
    }

    /**
     * 开启定位
     */
    private void startLocation(){
        locationClient.startLocation();
    }

    /**
     * 默认的定位参数
     * @since 2.8.0
     * @author hongming.wang
     *
     */
    private AMapLocationClientOption getDefaultOption(){
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setGpsFirst(false);//可选，设置是否gps优先，只在高精度模式下有效。默认关闭
        mOption.setHttpTimeOut(30000);//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setInterval(2000);//可选，设置定位间隔。默认为2秒
        mOption.setNeedAddress(true);//可选，设置是否返回逆地理地址信息。默认是true
        mOption.setOnceLocation(false);//可选，设置是否单次定位。默认是false
        mOption.setOnceLocationLatest(false);//可选，设置是否等待wifi刷新，默认为false.如果设置为true,会自动变为单次定位，持续定位时不要使用
        AMapLocationClientOption.setLocationProtocol(AMapLocationClientOption.AMapLocationProtocol.HTTP);//可选， 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
        mOption.setSensorEnable(false);//可选，设置是否使用传感器。默认是false
        mOption.setWifiScan(true); //可选，设置是否开启wifi扫描。默认为true，如果设置为false会同时停止主动刷新，停止以后完全依赖于系统刷新，定位位置可能存在误差
        mOption.setLocationCacheEnable(true); //可选，设置是否使用缓存定位，默认为true
        mOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT);//可选，设置逆地理信息的语言，默认值为默认语言（根据所在地区选择语言）
        return mOption;
    }

    /**
     * 设置地图等各项信息
     */
    private void setUpMap(){
        pathList = PathUtils.GetPathList(mapVo);
        LatLngBounds.Builder b = LatLngBounds.builder();
        for(int i = 0; i < pathList.size(); i++){
            b.include(pathList.get(i));
        }
        LatLngBounds bounds = b.build();
        map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 100));
        startLocation = pathList.get(0);
        endLocation = pathList.get(pathList.size() - 1);
        Iterable<LatLng> pathIter = pathList;
        L.e("list =  " +pathList);
        polyline = map.addPolyline((new PolylineOptions()).addAll(pathIter).width(10).color(Color.argb(255, 1, 1, 1)));
        startMarker = map.addMarker(new MarkerOptions().position(startLocation).icon(BitmapDescriptorFactory.fromResource(R.drawable.start)));
        endMarker = map.addMarker(new MarkerOptions().position(endLocation).icon(BitmapDescriptorFactory.fromResource(R.drawable.end)));

    }

    /**
     * 重置小人图标
     */
    private void resetRoleMarker(){
        roleMarker = new SmoothMoveMarker(map);
        roleMarker.setDescriptor(BitmapDescriptorFactory.fromResource(R.drawable.walk003));
        roleMarker.setRotate(180);
        LatLng walkPoint = startLocation;
        Pair<Integer, LatLng> pair = SpatialRelationUtil.calShortestDistancePoint(pathList, walkPoint);
        pathList.set(pair.first, walkPoint);
        List<LatLng> subList = pathList.subList(pair.first, pathList.size());
        roleMarker.setPoints(subList);
        roleMarker.setTotalDuration(10);

        roleMarker.setMoveListener(new SmoothMoveMarker.MoveListener() {
            @Override
            public void move(final double distance) {
                Log.i("MY","distance:  "+distance);
                if(distance == 0){
                    endTime();
                    isPublishComment();
                }
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        int allDistance = mapVo.getDistince();
                        double hasDistance = allDistance - distance;
                        distanceText.setText(NumberUtils.getFormatDouble(hasDistance) + "");
                    }
                });
            }
        });
    }

    /**
     * 是否发布社区分享
     */
    private void isPublishComment(){
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                final AlertDialog.Builder builder = new AlertDialog.Builder(StartRunActivity.this);
                builder.setMessage("是否保存本次数据？");
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        getScreenPic();
                    }
                });
                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        builder.create().dismiss();
                        return;
                    }
                });
                builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    @Override
                    public void onDismiss(DialogInterface dialogInterface) {
                        setScreenBgLight();
                    }
                });
                builder.create().show();
            }
        });

    }

    /**
     * 得到地图截图
     */
    private void getScreenPic(){
        map.getMapScreenShot(new AMap.OnMapScreenShotListener() {
            @Override
            public void onMapScreenShot(Bitmap bitmap) {

            }

            @Override
            public void onMapScreenShot(Bitmap bitmap, int status) {
                String path = "";
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
                if(null == bitmap){
                    return;
                }
                try {
                    String sdCardPath = Environment.getExternalStorageDirectory().getPath();
                    // 图片文件路径
                    path = sdf.format(new Date()) + ".jpeg";
                    String filePath = sdCardPath + File.separator + path;

                    File file = new File(filePath);
                    FileOutputStream os = new FileOutputStream(file);
                    boolean b = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
                    try {
                        os.flush();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    StringBuffer buffer = new StringBuffer();
                    if (b)
                        buffer.append("截屏成功 ");
                    else {
                        buffer.append("截屏失败 ");
                    }
                    if (status != 0)
                        buffer.append("地图渲染完成，截屏无网格");
                    else {
                        buffer.append( "地图未渲染完成，截屏有网格");
                    }
                    ToastUtil.MakeToast(buffer.toString());

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }finally {
                    RunRecordVo recordVo = getRunRecord();
                    final String recordVoStr = GsonUtil.GenerateJsonStr(recordVo);
                    L.e("上传数据" + recordVoStr);
                    startPublishRecord(recordVo);
                }

            }
        });
    }

    /**
     * 开始发布跑步记录
     * @param recordVo
     */
    public void startPublishRecord(final RunRecordVo recordVo){
        showProgressDialog();
        final String recordVoStr = GsonUtil.GenerateJsonStr(recordVo);
        L.e("上传数据" + recordVoStr);
        RequestBody body = new FormBody.Builder()
                .add("runRecordVo", recordVoStr)
                .build();
        Request request = CommonRequest.createPostRequest(UrlConstants.PUBLISH_RECORD, body);
        CommonOkHttpClient.post(request, new DisposeDataHandle(new DisposeDataListener() {
            @Override
            public void onSuccess(String responseStr) {
                closeProgressDialog();
                L.e(responseStr);
                ServerResponse response = GsonUtil.formatJsonToServerResponse(responseStr);
                if(response != null && response.isSuccess()){
                    ToastUtil.MakeToast(response.getMsg());
                    Intent intent = new Intent(StartRunActivity.this, GenSharePicActivity.class);
                    ShareDataVo vo = getShareVo(recordVo);
                    intent.putExtra(Const.START_SHARE, GsonUtil.GenerateJsonStr(vo));
                    startActivity(intent);
                }else {
                    onFailure(new OkHttpException(ResponseCode.ERROR.getCode(), ResponseCode.ILLEGAL_ARGUMENT.getValue()));
                }

            }

            @Override
            public void onFailure(OkHttpException e) {
                ToastUtil.MakeToast(e.getMsg().toString());
            }
        }));
    }

    /**
     * 根据信息得到跑步记录信息实体类对象
     * @return
     */
    public RunRecordVo getRunRecord(){
        String[] timeStrs = timeText.getText().toString().trim().split(":");
        int time = 0;
        int min = Integer.parseInt(timeStrs[0]);
        int second = Integer.parseInt(timeStrs[1]);
        time = second + 60 * min;

        RunRecordVo recordVo = new RunRecordVo();
        UserDB user = LitePal.findFirst(UserDB.class);
        recordVo.setUserId(user.getTagId());
        recordVo.setMapId(mapVo.getId());
        recordVo.setUserName(user.getUsername());
        recordVo.setTime(time);
        recordVo.setDistance(mapVo.getDistince());
        recordVo.setDate(DateParseUtil.dateToString(new Date()));
        recordVo.setPicUrl(getBackUrl());
        recordVo.setPathList(PathUtils.GetPathList1(mapVo, user.getTagId()));
        return recordVo;
    }

    /**
     * 根据跑步路径获得路径图片地址
     * @return
     */
    public String getBackUrl(){
        List<LatLng> pathList = PathUtils.GetPathList(mapVo);
        String backImgUrl = MyMapUtils.GETPathPicUrl2(pathList);
        return backImgUrl;
    }

    /**
     * 得到分享记录实体类对象
     * @param recordVo
     * @return
     */
    private ShareDataVo getShareVo(RunRecordVo recordVo){
        ShareDataVo vo = new ShareDataVo();
        UserDB db = LitePal.findFirst(UserDB.class);
        vo.setUserId(db.getTagId());
        vo.setDateTime(DateParseUtil.dateToString(new Date()));
        vo.setDistance(MyNumberUtils.getDistanceKMFromM(mapVo.getDistince()));
        vo.setTime(timeText.getText().toString().trim());
        vo.setBackUrl(recordVo.getPicUrl());
        vo.setUsername(db.getUsername());
        vo.setHeadUrl(db.getFaceImage());
        return vo;
    }

    /**
     * 从上一界面获取地图信息
     */
    private void getData(){
        Intent intent = getIntent();
        mapId = intent.getLongExtra(Const.GET_MAP_ID, -1);
        if(mapId == -1){
            ToastUtil.MakeToast("mapId不符格式");
            return;
        }
        RequestBody body = new FormBody.Builder().add("id", String.valueOf(mapId)).build();
        Request request = CommonRequest.createPostRequest(UrlConstants.MAP_GET_MAP, body);
        CommonOkHttpClient.post(request, new DisposeDataHandle(new DisposeDataListener() {
            @Override
            public void onSuccess(String responseStr) {
                ServerResponse<RunMapRouteVo> response = GsonUtil.formatJsonToMapRouteVo(responseStr);
                if(response == null){
                    onFailure(new OkHttpException(ResponseCode.ERROR.getCode(), ResponseCode.NETWORK_ERROR.getValue()));
                    return;
                }
                if(response.isSuccess()){
                    mapVo = response.getData();
                    L.e("pathData = " + mapVo);
                    setUpMap();
                }else {
                    ToastUtil.MakeToast(response.getMsg());
                }
            }

            @Override
            public void onFailure(OkHttpException e) {
                ToastUtil.MakeToast(e.getMsg().toString());
            }
        }));
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    /**
     * 开始虚拟跑步
     */
    private void startRun(){
        resetRoleMarker();
        startTime();
        startBtn.setClickable(false);
        endBtn.setClickable(true);
        roleMarker.startSmoothMove();
        endBtn.setVisibility(View.VISIBLE);
        startBtn.setImageResource(R.drawable.pause);
    }

    /**
     * 结束虚拟跑步
     */
    private void endRun(){
        endTime();
        startBtn.setClickable(true);
        endBtn.setClickable(false);
        timeUtils.getTextView().setText("00:00");
        roleMarker.stopMove();
        roleMarker.setVisible(false);
        resetRoleMarker();
        distanceText.setText("0.00");
        startBtn.setImageResource(R.drawable.start_icon);
        endBtn.setVisibility(View.GONE);
    }

    /**
     * 时间计数开始
     */
    private void startTime(){
        timeUtils.getTextView().setText("00:00");
        timeUtils.startTime();
    }

    /**
     * 重新开始时间
     */
    private void restartTime(){
        timeUtils.startTime();
    }

    /**
     * 暂停开始时间
     */
    private void pauseTime(){
        timeUtils.pauseTime();
    }

    /**
     * 结束时间
     */
    private void endTime(){
        timeUtils.stopTimer();
    }

    /**
     * 开始真实跑步
     */
    private void startActualRun(){
        startTime();
        status = 1;
        aMapNavi = AMapNavi.getInstance(this);
        aMapNavi.setUseInnerVoice(true);
        boolean isLocation = LocationUtils.IsLocation(nowLocation, startLocation);
        if(!isLocation){
            ToastUtil.MakeToast("请先移动到起始点" + mapVo.getRunRouteVos().get(0).getStreet());
            L.e("没有定位, 目前位置为" + nowLocation);
            actualRoleMarker = map.addMarker(new MarkerOptions().position(nowLocation).icon(BitmapDescriptorFactory.fromResource(R.drawable.walk003)));
            locationClient.stopLocation();
            return;
        }
        actualRoleMarker = map.addMarker(new MarkerOptions().position(nowLocation).icon(BitmapDescriptorFactory.fromResource(R.drawable.walk003)));
        actualPathList.add(nowLocation);
    }

    /**
     * 暂停真实跑步
     */
    private void pauseActualRun(){
        pauseTime();
        startBtn.setImageResource(R.drawable.start_icon);
    }

    /**
     * 重启真实跑步
     */
    private void restartActualRun(){
        restartTime();
        startBtn.setImageResource(R.drawable.pause);
    }

    /**
     * 结束真实跑步
     */
    private void endActualRun(){
        endTime();
        boolean isLocation = LocationUtils.IsLocation(nowLocation, endLocation);
        if(!isLocation){
            final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
            dialog.setMessage("还没有到达终点，是否停止运动,记录将不会保存");
            dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                }
            });
            dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
//                    dialog.dismiss();
                    return;
                }
            });
            dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override
                public void onDismiss(DialogInterface dialogInterface) {
                    setScreenBgLight();
                }
            });
            dialog.show();
            setScreenBgDarken();
        }else{
            ToastUtil.MakeToast("运动完成，正在上传运动数据");
            uploadRunRecord();
        }
    }

    /**
     * 上传跑步记录
     */
    private void uploadRunRecord() {
        UserDB userDB = LitePal.findFirst(UserDB.class);
        Long userId = userDB.getTagId();
        int useTime = (int) timeUtils.count;
        Long mapId = mapVo.getId();
        RequestBody body = new FormBody.Builder().
                add("mapId", String.valueOf(mapId)).
                add("userId", String.valueOf(userId)).
                add("useTime", String.valueOf(useTime)).
                build();
        Request request = CommonRequest.createPostRequest(UrlConstants.MAP_UPLOAD_RECORD, body);
        CommonOkHttpClient.post(request, new DisposeDataHandle(new DisposeDataListener() {
            @Override
            public void onSuccess(String responseStr) {
                ServerResponse response = GsonUtil.formatJsonToServerResponse(responseStr);
                if(response == null){
                    onFailure(new OkHttpException(ResponseCode.ERROR.getCode(), ResponseCode.NETWORK_ERROR.getValue()));
                    return;
                }
                if(response.isSuccess()){
                    ToastUtil.MakeToast(response.getMsg());
                }else {
                    ToastUtil.MakeToast(response.getMsg());
                    StartRunActivity.this.finish();
                }
            }

            @Override
            public void onFailure(OkHttpException e) {
                ToastUtil.MakeToast(e.getMsg().toString());
            }
        }));


    }

    /**
     * 设置屏幕暗
     */
    private void setScreenBgDarken(){
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = 0.5f;
        lp.dimAmount = 0.5f;
        getWindow().setAttributes(lp);
    }

    // 设置屏幕背景变亮
    private void setScreenBgLight() {
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = 1.0f;
        lp.dimAmount = 1.0f;
        getWindow().setAttributes(lp);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.start_run_btn:
                startRun();
                break;
            case R.id.end_run_btn:
                endRun();
                break;
            default:
                break;
        }
    }

    @Override
    public boolean onLongClick(View view) {
        switch (view.getId()){
            case R.id.start_run_btn:
                switch (status){
                    case 0:
                        startLocation();
                        break;
                    case 1:
                        pauseActualRun();
                        break;
                    case 2:
                        restartActualRun();
                        break;
                    default:
                        break;

                }
                return true;
            case R.id.end_run_btn:
                endActualRun();
                break;
            default:
                return false;
        }
        return false;
    }


    /**
     * 显示进度对话框
     */
    private void showProgressDialog(){
        if(progressDialog == null){
            progressDialog = new ProgressDialog(this);
            progressDialog.setMessage("正在加载...");
            progressDialog.setCanceledOnTouchOutside(false);
        }
        progressDialog.show();
    }

    /**
     * 关闭进度对话框
     */
    private void closeProgressDialog(){
        if(progressDialog != null){
            progressDialog.dismiss();
        }
    }
}
